package com.isp.common.model.map;

import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 无顺序key的map
 * put（"A", "B", "v1"）
 * put（"A", "c", "v2"）
 * get（"B", "A"）= "v1"
 * put ("B", "A", "v3")
 * get（"B", "A"）= "v3"
 *
 * @param <K1> key1
 * @param <K2> key2
 * @param <V>  值
 */
public class ConcurrentUnorderedMultipleKeyMap<K1, K2, V> {

    private final ConcurrentHashMap<Pair<K1, K2>, V> MAP = new ConcurrentHashMap<>();

    public void put(K1 key1, K2 key2, V value) {
        Pair<K1, K2> sortedKeys = sortKeys(key1, key2);
        MAP.put(sortedKeys, value);
    }

    public V get(K1 key1, K2 key2) {
        Pair<K1, K2> sortedKeys = sortKeys(key1, key2);
        return MAP.get(sortedKeys);
    }

    private Pair<K1, K2> sortKeys(K1 key1, K2 key2) {
        return new Pair<>(key1, key2);
    }

    private static class Pair<K1, K2> {
        K1 key1;
        K2 key2;

        public Pair(K1 key1, K2 key2) {
            this.key1 = key1;
            this.key2 = key2;
        }

        @Override
        public int hashCode() {
            return Objects.hash(key1, key2) + Objects.hash(key2, key1); // 两个键的组合顺序不同，但hashCode一样
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj == null || getClass() != obj.getClass()) {
                return false;
            }
            Pair<?, ?> pair = (Pair<?, ?>) obj;
            return (Objects.equals(key1, pair.key1) && Objects.equals(key2, pair.key2)) ||
                    (Objects.equals(key1, pair.key2) && Objects.equals(key2, pair.key1));
        }
    }

    public static void main(String[] args) {
        ConcurrentUnorderedMultipleKeyMap<String, String, String> customMap = new ConcurrentUnorderedMultipleKeyMap<>();
        customMap.put("A", "B", "Value1");
//        customMap.put("B", "A", "Value2");
        customMap.put("C", "D", "Value3");

        System.out.println(customMap.get("A", "B")); // 输出 "Value1"
        System.out.println(customMap.get("B", "A")); // 输出 "Value1"
        System.out.println(customMap.get("C", "D")); // 输出 "Value3"
    }
}
